/*******************************************************************\
| RayTracer.h
|
| CREATED:		4.6.2009
| DESCRIPTION:
| 
| Ray Tracer class.
| This class implements the actual ray tracer that draws a given
| scene to an output buffer.
| The code is based on Jacco Bikker's ray tracing tutorials at
| http://www.devmaster.net/articles/raytracing_series/part1.php
\********************************************************************/
#ifndef RAYTRACER_H
#define RAYTRACER_H

#include "Scene.h"
#include "PhotonMap.h"
#include "RayTraceRecorder.h"

namespace PhotonMapping
{

//*****************************************************************************
// class overview:
//   
//-----------------------------------------------------------------------------
class RayTracer
{
	public:

		RayTracer();

		// draws the current scene into p_Buffer
		void Draw(ScenePtr p_Scene, std::vector<Color>& p_Buffer, int p_Width, int p_Height);

		// draws the current scene using photon mapping into p_Buffer
		void Draw(ScenePtr p_Scene, PhotonMapPtr p_GlobalPM, PhotonMapPtr p_CausticPM, std::vector<Color>& p_Buffer, int p_Width, int p_Height);

		// draws the photon map
		void DrawPhotonMap(ScenePtr p_Scene, PhotonMapPtr p_PM, const intx p_Width, const intx p_Height, std::vector<Color>& p_Buffer);

	private:
		// traces the given ray through the scene and returns the pixel color
		Color RayTrace(ScenePtr p_Scene, const Math::Ray& p_Ray, const uintx p_SpecBounces);

		// traces the given ray through the scene and returns the pixel color using photon mapping
		Color RayTracePM(ScenePtr p_Scene, PhotonMapPtr p_GlobalPM, PhotonMapPtr p_CausticPM, const Math::Ray& p_Ray, const uintx p_DiffBounces, const uintx p_SpecBounces);

		// traces the given ray through scene and records all hits in the ray trace recorders
		void RayTraceDeferred(ScenePtr p_Scene, RayTraceRecorderPtr p_Global, RayTraceRecorderPtr p_Caustic, const Math::Ray& p_Ray, const uintx p_DiffBounces, const uintx p_SpecBounces, Color* p_CurBufOut, const Color& p_PrevFactor);

		// calculate local illumination for the given point
		Color LocalIllumination(ScenePtr p_Scene, const Math::Ray& p_ViewRay, const Math::Vector3& p_Pos, const Math::Vector3& p_Normal, MaterialPtr p_Material);


		// sampling kernels
		static const intx MaxTraces = 8;

		static const intx SpecTraces = 3;
		static const intx RefrTraces = 5;
};

}

#endif // RAYTRACER_H
